package www.ld.com.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import www.ld.com.dictionary.UseStatusEnum;
import www.ld.com.domain.department.pojo.DepartmentPO;
import www.ld.com.domain.dto.user.UserInfoDTO;
import www.ld.com.domain.post.pojo.PostPO;
import www.ld.com.domain.roles.pojo.RolesPO;
import www.ld.com.domain.user.pojo.UserPO;
import www.ld.com.domain.user.query.UserQuery;
import www.ld.com.domain.user.vo.OutUserVO;
import www.ld.com.exception.ValidateException;
import www.ld.com.mapper.DepartmentMapper;
import www.ld.com.mapper.PostMapper;
import www.ld.com.mapper.RolesMapper;
import www.ld.com.mapper.UserMapper;
import www.ld.com.utils.SecurityUtils;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import java.util.List;
import java.util.Set;

@Service
public class UserService {
    @Resource
    private UserMapper userMapper;
    @Resource
    private PostMapper postMapper;
    @Resource
    private RolesMapper rolesMapper;
    @Resource
    private DepartmentMapper departmentMapper;


    public Page<UserPO> pageUserByUserQuery(UserQuery userQuery) {
        return userMapper.selectPage(
                new Page<UserPO>(userQuery.getCurrent(), userQuery.getSize()),
                new LambdaQueryWrapper<UserPO>()
                        .like(StrUtil.isNotBlank(userQuery.getName()), UserPO::getName, userQuery.getName())
                        .eq(StrUtil.isNotBlank(userQuery.getUsername()), UserPO::getUsername, userQuery.getUsername())
        );
    }

    @Transactional
    public void saveUserPO(UserPO userPO, List<String> postId, List<String> rolesIds) {
        validateRelationStatus(postId, rolesIds, userPO.getDepartmentId());
        userPO.setPassword(SecurityUtils.encryptPassword(userPO.getPassword()));
        userMapper.insert(userPO);
        if (CollUtil.isNotEmpty(postId)) {
            userMapper.insertPostId(postId, userPO.getId());
        }
        if (CollUtil.isNotEmpty(rolesIds)) {
            userMapper.insertRolesId(rolesIds, userPO.getId());
        }
    }

    @Transactional
    @CacheEvict(key = "#p0.username",cacheNames = "user:info")
    public void updateUserPOById(UserPO userPO, List<String> postId, List<String> rolesIds) {
        validateRelationStatus(postId, rolesIds, userPO.getDepartmentId());
        if (StrUtil.isNotBlank(userPO.getPassword())) {
            userPO.setPassword(SecurityUtils.encryptPassword(userPO.getPassword()));
        } else {
            UserPO temp = userMapper.selectById(userPO.getId());
            userPO.setPassword(temp.getPassword()).setUsername(temp.getUsername());
        }
        userMapper.updateById(userPO);
        userMapper.deletePostId(userPO.getId());
        if (CollUtil.isNotEmpty(postId)) {
            userMapper.insertPostId(postId, userPO.getId());
        }
        userMapper.deleteRolesId(userPO.getId());
        if (CollUtil.isNotEmpty(rolesIds)) {
            userMapper.insertRolesId(rolesIds, userPO.getId());
        }
    }

    /**
     * 验证关联 角色、机构、部门的状态
     *
     * @param postId
     */
    public void validateRelationStatus(List<String> postId, List<String> rolesIds, Long departmentId) {
        if (CollectionUtil.isNotEmpty(postId)) {
            PostPO postPO = postMapper.selectOnePostByIdAndStatus(postId, UseStatusEnum.STOP_USING);
            if (ObjectUtil.isNotNull(postPO)) {
                throw new ValidateException("保存失败：岗位名为:【" + postPO.getName() + "】状态被停用");
            }
        }
        if (CollectionUtil.isNotEmpty(rolesIds)) {
            RolesPO rolesPO = rolesMapper.selectOneRolesByIdAndStatus(rolesIds, UseStatusEnum.STOP_USING);
            if (ObjectUtil.isNotNull(rolesPO)) {
                throw new ValidateException("保存失败：角色名为:【" + rolesPO.getName() + "】状态被停用");
            }
        }
        if (ObjectUtil.isNotNull(departmentId)) {
            DepartmentPO departmentPO = departmentMapper.selectById(departmentId);
            if (departmentPO.getStatus() == UseStatusEnum.STOP_USING) {
                throw new ValidateException("保存失败：部门名为:【" + departmentPO.getName() + "】状态被停用");
            }
        }
    }


    public OutUserVO getOutUserVOById(String id) {
        UserPO userPO = userMapper.selectById(id);
        OutUserVO outUserVO = BeanUtil.toBean(userPO, OutUserVO.class);
        outUserVO.setPostIds(userMapper.findPostIdByUserId(id));
        outUserVO.setRolesIds(userMapper.findRolesIdByUserId(id));
        return outUserVO;
    }
    @CacheEvict(cacheNames = "user:info",allEntries = true)
    public void deleteUserById(String id) {
        userMapper.deleteById(id);
        userMapper.deletePostId(Long.valueOf(id));
        userMapper.deleteRolesId(Long.valueOf(id));
    }

    @Cacheable(cacheNames = "user:info",key = "#p0")
    public UserInfoDTO getUserInfoDTOByUsername(@NotBlank String username) {
        UserPO userPO = userMapper.selectOne(new LambdaQueryWrapper<UserPO>().eq(UserPO::getUsername, username));
        if (ObjectUtil.isNull(userPO)) return null;
        Set<String> authorities = userMapper.findResourceByUserId(String.valueOf(userPO.getId()));
        UserInfoDTO userInfo = new UserInfoDTO(String.valueOf(userPO.getId()), userPO.getName(), userPO.getUsername(), userPO.getPassword(), userPO.getStatus(), authorities);
        return userInfo;
    }
}
